/*
 * MainWindow.cpp
 *
 *  Created on: 11.04.2010
 *      Author: king
 */

#include <QInputDialog>
#include <QMessageBox>
#include <QFileDialog>
#include "MainWindow.h"
#include "PersonType.h"
#include "genealogy_tree/Photo.h"
#include "db/GenealogyTreeUtils.h"

namespace etu {
namespace ui {

using etu::genealogy_tree::Photo;

static const QString ABOUT_STRING = "Генеалогическое дерево\n\n© Ботян И.Ю., Воробьёва М.М.,\nКоролёв Ю.А., Овчаренко А.С.\n\nСПбГЭТУ, 2010 г.\n";

CMainWindow::CMainWindow()
{
    setupUi(this);

    m_addDialog = new CAddPersonDialog(this);
    m_findDialog = new CFindDialog(this);

    m_dataSource = new SqliteDataSource(DB_URL);
    DataSourceManager::setDataSource(m_dataSource);
    m_aboutPerson->init(m_dataSource);
    m_diagram->init(m_dataSource);

    m_actions.push_back(m_saveAction);
    m_actions.push_back(m_saveAsAction);
    m_actions.push_back(m_deleteAction);
    m_actions.push_back(m_searchAction);
    m_actions.push_back(m_exportAction);
    m_actions.push_back(m_getSibsAction);
    m_actions.push_back(m_revertAction);

    setEnableStatus(false);
    showMaximized();

    connect(m_createRootAction, SIGNAL(triggered()), m_addDialog, SLOT(showDialog()));
    connect(m_saveAsAction, SIGNAL(triggered()), this, SLOT(saveTreeAs()));
    connect(m_loadFromDbAction, SIGNAL(triggered()), this, SLOT(loadTree()));
    connect(m_addDialog, SIGNAL(createNewPerson(Person, PersonType)), m_diagram, SLOT(createNewPerson(Person, PersonType)));
    connect(m_addDialog, SIGNAL(changeEnableStatus(bool)), this, SLOT(setEnableStatus(bool)));
    connect(m_diagram, SIGNAL(addFather(PersonType)), m_addDialog, SLOT(showDialog(PersonType)));
    connect(m_diagram, SIGNAL(addMother(PersonType)), m_addDialog, SLOT(showDialog(PersonType)));
    connect(m_diagram, SIGNAL(addChild(PersonType)), m_addDialog, SLOT(showDialog(PersonType)));
    connect(m_diagram, SIGNAL(selectPerson(Person*,QPixmap*)), m_aboutPerson, SLOT(setPerson(Person*,QPixmap*)));
    connect(m_diagram, SIGNAL(deletePerson(bool)), m_aboutPerson, SLOT(setDisabled(bool)));
    connect(m_aboutPerson, SIGNAL(aboutPersonChange()), m_diagram, SLOT(updateCurrentNode()));
    connect(m_aboutPerson, SIGNAL(updatePhoto(QPixmap*)), m_diagram, SLOT(updatePhoto(QPixmap*)));
    connect(m_quitAction, SIGNAL(triggered()), this, SLOT(close()));
    connect(m_deleteAction, SIGNAL(triggered()), this, SLOT(deleteTree()));
    connect(m_saveAction, SIGNAL(triggered()), this, SLOT(saveTree()));
    connect(m_searchAction, SIGNAL(triggered()), m_findDialog, SLOT(show()));
    connect(m_findDialog, SIGNAL(searchPerson(Person*)), m_diagram, SLOT(search(Person*)));
    connect(m_importAction, SIGNAL(triggered()), this, SLOT(importTree()));
    connect(m_exportAction, SIGNAL(triggered()), this, SLOT(exportTree()));
    connect(m_getSibsAction, SIGNAL(triggered()), m_diagram, SLOT(showSibs()));
    connect(m_aboutAction, SIGNAL(triggered()), this, SLOT(showAboutView()));
    connect(m_revertAction, SIGNAL(triggered()), this, SLOT(revertTree()));
}

void CMainWindow::saveTreeAs()
{
  std::string fileName = getTreeName();

  if (!fileName.empty())
	saveTreeToDB(fileName);
}

std::string CMainWindow::getTreeName()
{
  bool ok;
  QString  text = QInputDialog::getText(this, tr("Сохранить генеалогическое дерево"),
			           tr("Имя дерева в БД:"),QLineEdit::Normal,"",&ok);

  std::string fileName = QString(text.toUtf8()).toStdString();

  if (ok && !fileName.empty())
	return fileName;

  return std::string();
}

void CMainWindow::saveTree()
{
   if (!m_treeName.empty())
   {
	 saveTreeToDB( m_treeName);
	 QMessageBox::information(this, tr("Сохранение дерева"),
	  		   tr("Дерево сохранено в БД"),QMessageBox::Ok);
   }
   else
	 saveTreeAs();
}

void CMainWindow::loadTree()
{
  CTreeLoadDialog* dialog = new CTreeLoadDialog(this,m_dataSource->getGenealogyTreeNames());
  connect(dialog, SIGNAL(deleteTree(std::string)), this, SLOT(deleteTreeFromDB(std::string)));
  connect(dialog, SIGNAL(loadTree(std::string)), this, SLOT(loadTreeFromDB(std::string)));

  dialog->show();
}

void CMainWindow::loadTreeFromDB(std::string name)
{
  m_treeName = name;
  m_diagram->setTree(m_dataSource->getGenealogyTree(name));
  setEnableStatus(true);
  m_revertAction->setEnabled(true);
}

void CMainWindow::deleteTreeFromDB(std::string name)
{
  m_dataSource->deleteGenealogyTree(name);
}

void CMainWindow::saveTreeToDB(std::string name)
{
  if (!m_dataSource->isGenealogyTreeExists(name))
	m_dataSource->addGenealogyTree(name,*m_diagram->getTree());
  else
    m_dataSource->updateGenealogyTree(name,*m_diagram->getTree());

  m_treeName = name;
}

void CMainWindow::deleteTree()
{
  if (!m_treeName.empty())
  {
     int ret = QMessageBox::question(this, tr("Удалить дерево"),
    		   tr("Удалить дерево из БД?"),QMessageBox::Ok|QMessageBox::Cancel);

     if (ret == QMessageBox::Cancel)
     	 return;

	 deleteTreeFromDB(m_treeName);
     m_treeName.clear();
  }
  setEnableStatus(false);
  m_diagram->clear();
  m_aboutPerson->setDisabled(true);
}

void CMainWindow::setEnableStatus(bool flag)
{
    for(size_t i=0; i<m_actions.size(); ++i)
    	m_actions[i]->setEnabled(flag);

    if (m_treeName.empty())
      m_revertAction->setEnabled(false);
}

void CMainWindow::showAboutView()
{
   QMessageBox::information(this, tr("О программе"), tr(ABOUT_STRING.toStdString().c_str()),QMessageBox::Ok);
}

void CMainWindow::importTree()
{
	QString fileName = QFileDialog::getOpenFileName(this, tr("Import tree"),"","Tree (*.tree)");

	if (fileName.isEmpty())
		return;

	std::string treeName = getTreeName();

	if (!treeName.empty())
	try
	{
	  etu::genealogy_tree::GenealogyTreeUtils::importTree(QString(fileName.toUtf8()).toStdString(),treeName);
	  loadTreeFromDB(treeName);
	}
	catch(etu::db::DataSourceException& ex)
	{
	  QMessageBox::critical(this,tr("Ошибка импорта дерева из файла"),QString(tr(ex.what())));
	}
}

void CMainWindow::exportTree()
{
  QString fileName = QFileDialog::getSaveFileName(this, tr("Import tree"),"","Tree (*.tree)");

  try
  {
	etu::genealogy_tree::GenealogyTreeUtils::exportTree(QString(fileName.toUtf8()).toStdString(),m_treeName);
  }
  catch(etu::db::DataSourceException& ex)
  {
	 QMessageBox::critical(this,tr("Ошибка экспорта дерева в файл"),QString(tr(ex.what())));
  }
}

void CMainWindow::revertTree()
{
  if (!m_treeName.empty())
	  loadTreeFromDB(m_treeName);
}

}
}
